fix(client): Replace silent catch blocks across fetch handlers (closes #1058)#1119
Open
jeromehardaway wants to merge 2 commits into
Open
fix(client): Replace silent catch blocks across fetch handlers (closes #1058)#1119jeromehardaway wants to merge 2 commits into
jeromehardaway wants to merge 2 commits into
Conversation
Closes #1064. Extends src/lib/rate-limit.ts with applyRateLimit() — a small wrapper that sets X-RateLimit-* headers (and Retry-After on block) so each route opts in with one line. Applied limits: - /api/j0di3/* (per-user) 30 / 60s — every call hits a paid AI - /api/ai/chat (per-user) 20 / 60s — same reason, streaming - /api/contact (per-IP) 5 / 15m — paired with Gemini classifier - /api/newsletter (per-IP) 5 / 15m - /api/apply (per-IP) 3 / 60m - /api/mentor (per-IP) 5 / 60m - /api/mentee (per-IP) 5 / 60m - /api/health (per-IP) 60 / 60s — caps tight-loop pings Limits documented in docs/RATE_LIMITS.md (response shape, frontend conventions, how to add a new limit). Stayed on the existing in-memory bucketing — note in the doc that Redis/Upstash is the swap when we leave single-instance Vercel. Test fixtures for j0di3-proxy, /api/contact, and /api/health updated to include req.headers / req.socket / res.setHeader, and reset the bucket map via _resetRateLimitForTests in beforeEach so test order does not accumulate state.
Closes #1058. Adds src/utils/handle-client-error.ts with handleClientError() and getErrorMessage() — the single helper every silent catch should be migrated to. handleClientError always logs (so failures are no longer invisible) and has a TODO marker where Sentry / equivalent will plug in once we wire observability. Migrated every silent catch the issue called out plus a few near- misses found by walking the AST: - src/pages/challenges/index.tsx — fetchRecommended, fetchHistory, handleGetHint, handleShowSolution. Added per-section error states rendered inline so the user sees what failed instead of a hung spinner. - src/pages/challenges/[id].tsx — handleGetHint, handleShowSolution. Pipe failures into the existing `error` banner. - src/pages/challenges/browse.tsx — fetchTopics. Topic chips were legitimately a soft-fail; now logged for devs even though UX is unchanged. - src/components/profile/TroopDashboard.tsx — handleModuleChange, fetchDashboard, fetchWarmups, fetchProgress. Module change now surfaces a user-visible error. - src/components/jobs/ResumeScorer.tsx — handleFileUpload, handleDrop. Both already had hook-level error reporting; the helper just makes the underlying failure visible in the console / future observability sink. - src/components/translator/TranslatorForm.tsx — fetchDescription, PDF extract-fields fallback, PDF upload. Same hook pattern. - src/containers/profile/bio.tsx — fetchProfile, handleSave. Save now surfaces an inline banner on failure (it used to silently drop on the floor). Biome's `noEmptyBlockStatements` rule is already `error` for src/ and was being satisfied by `// non-critical` style comments inside the catch — that's why these slipped through. Documented this in the helper's JSDoc so future reviewers know what to insist on. Most of the line-count delta in JSX-heavy files is Biome auto-reformat on save (long lines wrapped to 100 cols); diff with --ignore-all-space to see the semantic changes only.
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Multiple client-side fetch handlers were swallowing errors with `catch { /* non-critical */ }` — spinners would stop, but nothing rendered and devs couldn't see what failed.
New `src/utils/handle-client-error.ts` exports a single `handleClientError(err, { context })` helper that every silent catch should migrate to. It always logs (with a `[context]` prefix so failures are searchable in the console) and has a TODO marker where Sentry / equivalent will plug in.
Migrated catches
Linting note
Biome's `noEmptyBlockStatements` rule is already `error` for `src/`. The empty catches were being satisfied by `// non-critical` style comments inside the body — that's why these slipped through. Documented this in the helper's JSDoc so future reviewers know what to insist on.
Diff size
Most of the line-count delta in JSX-heavy files (ResumeScorer, TroopDashboard, TranslatorForm) is Biome auto-reformat-on-write wrapping long lines to 100 cols. `git diff --ignore-all-space` shows the semantic changes only.
Closes #1058.
Test plan